package com.nq.stock.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.nq.common.ExchangeEnum;
import com.nq.common.entity.StStockIntroductionData;
import com.nq.common.entity.StStockTickerDetails;
import com.nq.common.entity.StStockTickerKLineList;
import com.nq.common.entity.StockTickerList;
import com.nq.common.entity.info.StockTickerListInfo;
import com.nq.common.entity.vo.StStockOnlyMarketAndCode;
import com.nq.common.entity.vo.StStockTickerDetailsVo;
import com.nq.dao.stock.StStockKLineMapper;
import com.nq.dao.stock.StStockMapper;
import com.nq.dao.stock.StStockTickerMapper;
import com.nq.pojo.SiteSetting;
import com.nq.service.ISiteSettingService;
import com.nq.stock.entity.*;
import com.nq.stock.service.IStStockService;
import com.nq.stock.service.IStStockTickerService;
import com.nq.stock.vo.StStockTickerKLineVO;
import com.nq.utils.stock.BuyAndSellUtils;
import com.nq.utils.task.tsanghi.StocksComponent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description: st_stock_ticker
 * @Author: jeecg-boot
 * @Date:   2024-05-30
 * @Version: V1.0
 */
@Service
@Slf4j
public class StStockTickerServiceImpl extends ServiceImpl<StStockTickerMapper, StStockTicker> implements IStStockTickerService {

    @Resource
    private StStockTickerMapper stStockTickerMapper;
    @Resource
    private StStockMapper stStockMapper;
    @Resource
    private StocksComponent stocksComponent;
    @Resource
    private StStockKLineMapper stStockKLineMapper;
    @Resource
    private IStStockService stStockService;
    @Resource
    private ISiteSettingService siteSettingService;

    @Override
    public int addStockTicker(List<StockTickerList> stockTickerList) {
        if (null == stockTickerList  || stockTickerList.size() == 0){
            return 0;
        }

        // 存储行情信息
        List<StStockTicker> stStockTickers = new ArrayList<>();
        // 存储基本信息
        ArrayList<StStock> stStocks = new ArrayList<>();

        for (StockTickerList stockTicker : stockTickerList) {
            StockTickerListInfo tickerMsg = stockTicker.getMsg();
            String stockName = tickerMsg.getName();
            if (StringUtils.isBlank(stockName)) {
                 continue;
            }
            // 需要过滤以_RE结尾的股票，_RE结尾的股票不能购买
            String code = stockTicker.getCode();
            if (code.indexOf("_RE") != -1) {
                continue;
            }

            StStockTicker ticker = stStockTickerMapper.queryByCode(tickerMsg.getMarket(), stockTicker.getCode());
            if (null != ticker) {
                StStockTicker updateTicker = new StStockTicker();
                updateTicker.setId(ticker.getId());
                updateTicker.setPrice(tickerMsg.getPrice());
                updateTicker.setVolume(tickerMsg.getVolume());
                updateTicker.setOpen(tickerMsg.getOpen());
                updateTicker.setHigh(tickerMsg.getHigh());
                updateTicker.setLow(tickerMsg.getLow());
                updateTicker.setChange(tickerMsg.getChange());
                updateTicker.setUp(tickerMsg.getUp());
                updateTicker.setClose(tickerMsg.getClose());
                // 需要根据B1 S1 判断涨跌停板  所以这里需要更新一下  其实不更新也行  反正交易时都会查实时的
                updateTicker.setS1(tickerMsg.getS1());
                updateTicker.setB1(tickerMsg.getB1());

                updateTicker.setUpdateTime(new Date());
                stStockTickerMapper.updateById(updateTicker);


                StStock stock = stStockMapper.queryByCode(tickerMsg.getMarket(), stockTicker.getCode());
                if (null != stock) {
                    StStock updateStock = new StStock();
                    updateStock.setId(stock.getId());
                    updateStock.setUpdateTime(new Date());
                    stStockMapper.updateById(updateStock);
                }
            }else {

                StStockTicker stStockTicker = new StStockTicker();
                stStockTicker.setCode(stockTicker.getCode());
                stStockTicker.setTick(tickerMsg.getTick());
                stStockTicker.setPrice(tickerMsg.getPrice());
                stStockTicker.setNv(tickerMsg.getNv());
                stStockTicker.setVmap(tickerMsg.getVmap());
                stStockTicker.setVolume(tickerMsg.getVolume());
                stStockTicker.setOpen(tickerMsg.getOpen());
                stStockTicker.setHigh(tickerMsg.getHigh());
                stStockTicker.setLow(tickerMsg.getLow());
                stStockTicker.setYs(tickerMsg.getYs());
                stStockTicker.setPosition(tickerMsg.getPosition());
                stStockTicker.setAmount(tickerMsg.getAmount());
                stStockTicker.setB1(tickerMsg.getB1());
                stStockTicker.setB1v(tickerMsg.getB1V());
                stStockTicker.setS1(tickerMsg.getS1());
                stStockTicker.setS1v(tickerMsg.getS1V());
                stStockTicker.setName(tickerMsg.getName());
                stStockTicker.setVarieties(tickerMsg.getVarieties());
                stStockTicker.setMarket(tickerMsg.getMarket());
                stStockTicker.setT(tickerMsg.getT());
                stStockTicker.setContract(tickerMsg.getContract());
                stStockTicker.setClose(tickerMsg.getClose());
                stStockTicker.setChange(tickerMsg.getChange());
                stStockTicker.setUp(tickerMsg.getUp());
                stStockTicker.setAmplitude(tickerMsg.getAmplitude());
                stStockTicker.setMrta(tickerMsg.getMrta());
                stStockTicker.setDealtransaction(tickerMsg.getDealTransaction());
                stStockTicker.setUpdateTime(new Date());
                stStockTickers.add(stStockTicker);
                stStockTickerMapper.insert(stStockTicker);

                StStock stock = stStockMapper.queryByCode(tickerMsg.getMarket(), stockTicker.getCode());
                if (null != stock) {
                    StStock updateStock = new StStock();
                    updateStock.setId(stock.getId());
                    updateStock.setUpdateTime(new Date());
                    stStockMapper.updateById(updateStock);
                    continue;
                }

                // 储存股票基本信息
                StStock stStock = new StStock();
                stStock.setName(tickerMsg.getName());
                stStock.setCode(stockTicker.getCode());
                stStock.setMarket(tickerMsg.getMarket());
                stStock.setContract(tickerMsg.getContract());
                stStock.setVarieties(tickerMsg.getVarieties());
                stStock.setCreateTime(new Date());
                stStocks.add(stStock);
                stStockMapper.insert(stStock);
            }

        }
        log.info("==============================股票基本信息更新开始===================stStocks条数： "+stStocks.size() + " stStockTickers条数： "+stStockTickers.size());
        // 新增行情
//        this.saveOrUpdateBatch(stStockTickers);
        // 新增基本信息
//        stStockService.saveOrUpdateBatch(stStocks);
        log.info("==============================股票基本信息更新结束=================== stStocks条数： "+stStocks.size() + " stStockTickers条数： "+stStockTickers.size());
        return 1;
    }


    @Override
    public StStockTickerDetailsVo queryDetails(String market, String code) {

        // 如果非交易时间直接查数据库
        SiteSetting siteSetting = siteSettingService.getSiteSetting();
        if(null == siteSetting){
            throw new RuntimeException("网站设置没有数据");
        }

        StStockTickerDetails info = stocksComponent.queryDetailsByMarketAndCode(market, code);

        // stocksComponent.thirdInterfaceStatistic(StocksComponent.MINI_PRICES, "queryDetails");

        if (null == info) {
            return assembleTheStockDetailData(market, code);
        }

        String longBusinessSummary = "无可用数据";
        StStockIntroduction introduction = stocksComponent.queryStockIntroductionByMarketAndCode(market, code);
        // stocksComponent.thirdInterfaceStatistic(StocksComponent.PROFILE, "queryDetails");

        if (null != introduction) {
            longBusinessSummary = introduction.getLongBusinessSummary();
        }
        StStockTickerDetailsVo detailsVo = new StStockTickerDetailsVo();
        BeanUtils.copyProperties(info, detailsVo);
        detailsVo.setLongBusinessSummary(longBusinessSummary);
        return detailsVo;
    }


    public StStockTickerDetailsVo assembleTheStockDetailData(String market, String code){
        StStockTickerDetails tickerDetails = new StStockTickerDetails();

        // 查询数据库
        QueryWrapper<StStockTicker> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("market", market);
        queryWrapper.eq("code", code);
        StStockTicker stockTicker = stStockTickerMapper.selectOne(queryWrapper);
        if (null != stockTicker) {
            StockTickerListInfo listInfo = new StockTickerListInfo();
            BeanUtils.copyProperties(stockTicker, listInfo);

            tickerDetails.setStatus("0");
            tickerDetails.setMarket(market);
            tickerDetails.setCode(code);
            tickerDetails.setData(listInfo);
        }

        String longBusinessSummary = "No data available";
        StStockIntroduction introduction = stocksComponent.queryStockIntroductionByMarketAndCode(market, code);
        // stocksComponent.thirdInterfaceStatistic(StocksComponent.PROFILE, "assembleTheStockDetailData");

        if (null != introduction) {
            longBusinessSummary = introduction.getLongBusinessSummary();
        }
        StStockTickerDetailsVo detailsVo = new StStockTickerDetailsVo();
        BeanUtils.copyProperties(tickerDetails, detailsVo);
        detailsVo.setLongBusinessSummary(longBusinessSummary);
        return detailsVo;
    }

    @Override
    public List<StStockOnlyMarketAndCode> selectOnlyMarketAndCode() {
        return stStockTickerMapper.selectOnlyMarketAndCode();
    }

    @Override
    @Transactional
    public int deleteByMarketAndCode(String market, String code) {

        stStockMapper.deleteByMarketAndCode(market, code);
        stStockTickerMapper.deleteByMarketAndCode(market, code);
        return 1;
    }

    @Override
    public StStockTickerKLineVO queryKLineDetails(String market, String code, String interval, String page) {

        StStockTickerKLineVO kLineVO = new StStockTickerKLineVO();
        StStockTickerKLineList kLineList = stocksComponent.queryKLineDetailsByMarketAndCode(market, code, interval, page);
        // stocksComponent.thirdInterfaceStatistic(StocksComponent.MINI_LIST, "queryKLineDetails");

        if (null == kLineList) {
            return kLineVO;
        }

        String data = kLineList.getData();
        if (StringUtils.isBlank(data)) {
            return kLineVO;
        }

        String[] splitData = data.split(";");
        List<String> dataList = Arrays.asList(splitData);

        List<KLineDetail> dataDetails = new ArrayList<>();

        // 处理具体的字段  1时间戳,1昨日收,1今日开,1最高,1最低,1交易额,1交易量;  1723766400,1.44,1.57,1.57,1.38,2200787.922,1509194.0
        for (String obj : dataList) {
            String[] split = obj.split(",");
            List<String> strings = Arrays.asList(split);
            if (strings.size() < 7) {
                continue;
            }
            KLineDetail kLineDetail = new KLineDetail();
            kLineDetail.setTimestamp(String.valueOf(Long.parseLong(strings.get(0))*1000));
            kLineDetail.setClose(strings.get(1));
            kLineDetail.setOpen(strings.get(2));
            kLineDetail.setHigh(strings.get(3));
            kLineDetail.setLow(strings.get(4));
            kLineDetail.setTurnover(strings.get(5));
            kLineDetail.setVolume(strings.get(6));
            dataDetails.add(kLineDetail);
        }

        BeanUtils.copyProperties(kLineList, kLineVO);

        // 按照时间戳生序
        dataDetails.sort(Comparator.comparing(KLineDetail::getTimestamp));

        // 新增最新的数据
        StStockTickerDetailsVo detailsVo = queryDetails(market, code);
        for (int i=0; i<dataDetails.size(); i++) {
            if (i == dataDetails.size() - 1) {
                StockTickerListInfo info = detailsVo.getData();
                KLineDetail detail = dataDetails.get(i);
                // 将当前价格给到昨收
                detail.setClose(String.valueOf(info.getPrice()));
                detail.setOpen(String.valueOf(info.getOpen()));
                detail.setHigh(String.valueOf(info.getHigh()));
                detail.setLow(String.valueOf(info.getLow()));
                detail.setVolume(String.valueOf(info.getVolume()));
                detail.setTurnover(String.valueOf(info.getAmount()));
            }
        }

        kLineVO.setData(dataDetails);
        return kLineVO;
    }

    @Override
    public int addStockKLine(StStockKLine kLine) {
        return stStockKLineMapper.insert(kLine);
    }

    @Override
    public StStockKLine queryKLineByMarketAndCode(String market, String code) {
        QueryWrapper<StStockKLine> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("market", market);
        queryWrapper.eq("code", code);
        return stStockKLineMapper.selectOne(queryWrapper);
    }

    @Override
    public int updateStockKLineById(StStockKLine kLine) {
        return stStockKLineMapper.updateById(kLine);
    }

    @Override
    public List<StStockKLine> queryKLineByMarket(String market) {
        QueryWrapper<StStockKLine> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("market", market);
        return stStockKLineMapper.selectList(queryWrapper);
    }

}
